package dawnland03.model.action.impl;

import dawnland03.model.action.ActionImpl;
import dawnland03.model.action.parameter.ActionInputParam;
import dawnland03.model.action.parameter.ActionOutputParam;
import dawnland03.model.action.ActionType;
import dawnland03.model.action.handler.ActionHandler;
import dawnland03.model.entity.Entity;
import dawnland03.model.entity.attribute.PhysicalAttribute;
import dawnland03.model.item.Item;
import dawnland03.model.item.ItemFactory;
import dawnland03.model.item.ItemType;
import org.apache.log4j.Logger;

import java.util.Map;
import java.util.LinkedList;
import java.util.List;

/**
 * User: Petru Obreja (obrejap@yahoo.com)
 * Date: May 9, 2010
 * Time: 9:55:25 PM
 */
public class GatherAction extends ActionImpl {

    private static Logger logger = Logger.getLogger(GatherAction.class.getName());

    GatherAction(Entity owner, Map<ActionInputParam, Object> actionInputParams,
                 Map<PhysicalAttribute, Integer> physicalAttributeRequirements,
                 Map<PhysicalAttribute, Double> physicalAttributeMultiplier,
                 long duration, ActionHandler actionHandler) {
        super(owner, ActionType.GATHER, actionInputParams,
                physicalAttributeRequirements, physicalAttributeMultiplier, duration, actionHandler);
    }

    @Override
    protected void endAction() {
        ItemType itemType = (ItemType) actionInputParams.get(ActionInputParam.ITEM_TYPE);
        int outputQuantity = computeOutput();
        if (logger.isDebugEnabled()) {
            logger.debug(owner + " gathered " + outputQuantity + " pieces of " + itemType);
        }
        List<Item> items = new LinkedList<Item>();
        for (int i = 1; i <= outputQuantity; i++) {
            Item item = ItemFactory.createItem(itemType, owner);
            items.add(item);
        }
        outputParameters.addOutputParamValue(ActionOutputParam.ITEM, items);
        for (PhysicalAttribute physicalAttribute : physicalAttributeRequirements.keySet()) {
            Double currentValue = owner.peekPhysicalAttribute(physicalAttribute);
            owner.increasePhysicalAttribute(physicalAttribute, 0.1 * (1 / currentValue));
        }
        outputParameters.addOutputParamValue(ActionOutputParam.COMPLETED, true);
        super.endAction();
    }

    /*
     * Formula: S = Sume((1+AttributeValue-AttributeRequirement)*AttributeMultiplier)
     *          Final Output: Math.floor(S/numberOfAttributeRequirements)
     */

    private Integer computeOutput() {
        double output = 0.0;
        for (PhysicalAttribute physicalAttribute : physicalAttributeRequirements.keySet()) {
            Integer physicalAttributeRequirement = physicalAttributeRequirements.get(physicalAttribute);
            Double physicalAttributeMultiplier = physicalAttributeMultipliers.get(physicalAttribute);
            Double physicalAttributeCoefficent = (1 + owner.peekPhysicalAttribute(physicalAttribute) - physicalAttributeRequirement) * physicalAttributeMultiplier;
            output += physicalAttributeCoefficent;
        }
        int numberOfAttributeRequirements = physicalAttributeRequirements.size();
        if (numberOfAttributeRequirements == 0) {
            numberOfAttributeRequirements = 1;
        }
        return (int) Math.floor(output / numberOfAttributeRequirements);
    }
}
